#pragma once

#include "mat.h"
#include "vec.h"


class Camera {
	mat4 cTransform;
	mat4 projection;
	mat4 toWorldTransformer; // multiply by this matrix in order to get the current world coordinates...
	vec4 placeInWorld;
	vec3 m_eye;
	vec3 m_at;
	vec3 m_up;
	bool m_is_ortho;
	vec2 center;
	GLfloat m_right;
	GLfloat m_left;
	GLfloat m_top;
	GLfloat m_bottom;
	GLfloat m_zNear;
	GLfloat m_zFar;
public:
	inline bool isOrtho() const { return m_is_ortho; }
	void setTransformation(const mat4& transform); // what the hell is this?!
	void LookAt(const vec3& eye, const vec3& at, const vec3& up );
	void Ortho( const GLfloat left, const GLfloat right,
		const GLfloat bottom, const GLfloat top,
		const GLfloat zNear, const GLfloat zFar );
	void Frustum( const float left, const float right,
		const float bottom, const float top,
		const float zNear, const float zFar );
	//similar to Frustum. So I changed the return value type to void...
	void Perspective( const float fovy, const float aspect,
		const float zNear, const float zFar);
	inline mat4 getCameraTransform() {return cTransform;}
	inline mat4 getProjectionTransform() { return projection; }
	inline mat4 getCorrector() { return toWorldTransformer; }
	inline vec4 getPlace() { return placeInWorld; }
	inline vec3 getUp() { return m_up; }
	inline vec3 getAt() { return m_at; }
	inline vec3 getEye() { return m_eye; }
	void Rotate(const GLfloat & x, const GLfloat & y, const GLfloat & z);
	void Move(const GLfloat & x, const GLfloat & y, const GLfloat & z);
	void UpdateProjection(const GLfloat & ratio);
	void Zoom(GLfloat rate);
	void getProjectionDimensions(GLfloat & width, GLfloat & height, GLfloat & depth);
	void MoveZNear(GLfloat len);
	void MoveZFar(GLfloat len);
};